package com.xinqi.modules.stats.score.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.xinqi.common.core.enums.ClassRoleEnum;
import com.xinqi.common.core.enums.TotalScoreTypeEnum;
import com.xinqi.common.mybatis.data.service.impl.BaseServiceImpl;
import com.xinqi.common.mybatis.utils.Queries;
import com.xinqi.modules.course.clazz.client.ClassStudentClient;
import com.xinqi.modules.course.clazz.dto.req.ClassStudentQueryDTO;
import com.xinqi.modules.course.clazz.dto.rsp.ClassStudentResultDTO;
import com.xinqi.modules.stats.score.convert.CourseTotalScoreConvert;
import com.xinqi.modules.stats.score.domain.CourseTotalScoreEntity;
import com.xinqi.modules.stats.score.domain.CourseTotalScoreStudentEntity;
import com.xinqi.modules.stats.score.dto.req.*;
import com.xinqi.modules.stats.score.dto.rsp.*;
import com.xinqi.modules.stats.score.mapper.CourseTotalScoreContentSonMapper;
import com.xinqi.modules.stats.score.mapper.CourseTotalScoreMapper;
import com.xinqi.modules.stats.score.mapper.CourseTotalScoreStudentMapper;
import com.xinqi.modules.stats.score.service.CourseTotalScoreConfigService;
import com.xinqi.modules.stats.score.service.CourseTotalScoreStudentService;
import com.xinqi.modules.stats.utils.MathUtils;
import lombok.RequiredArgsConstructor;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.stream.Collectors;

/**
 * 总成绩学生各栏目成绩基础数据表服务层实现
 *
 * @author: system
 * @date: 2023/03/26
 */
@Service("courseTotalScoreStudentService")
@RequiredArgsConstructor
public class CourseTotalScoreStudentServiceImpl extends BaseServiceImpl<CourseTotalScoreStudentMapper, CourseTotalScoreStudentEntity> implements CourseTotalScoreStudentService {

    private final CourseTotalScoreContentSonMapper courseTotalScoreContentSonMapper;

    private final CourseTotalScoreConvert courseTotalScoreConvert;

    private final ClassStudentClient classStudentClient;

    private final CourseTotalScoreConfigService courseTotalScoreConfigService;

    private final CourseTotalScoreMapper courseTotalScoreMapper;

    // PC总成绩柱状图统计
    @Override
    public CourseTotalScoreColumnResultDTO studentTotalScoreColumnList(CourseTotalScoreClassDTO dto) {

        CourseTotalScoreColumnResultDTO columnResultDTO = new CourseTotalScoreColumnResultDTO();

        // 获取总成绩总配置
        LambdaQueryWrapper<CourseTotalScoreEntity> wrapper = Queries.lambda();
        wrapper.eq(CourseTotalScoreEntity::getClassId, dto.getClassId());
        CourseTotalScoreResultDTO resultDTO = courseTotalScoreMapper.selectDtoOne(wrapper, courseTotalScoreConvert::convert);
        if (Objects.isNull(resultDTO) || Objects.isNull(resultDTO.getFullScore())) {
            CourseTotalScoreColumnResultDTO columnInfo = new CourseTotalScoreColumnResultDTO();
            return columnInfo;
        } else {
            if (resultDTO.getFullScore().compareTo(BigDecimal.ZERO) == 0) {
                CourseTotalScoreColumnResultDTO columnInfo = new CourseTotalScoreColumnResultDTO();
                return columnInfo;
            }
        }

        // 最大值、最小值、平均分查询
        CourseTotalScoreAllScoreResultDTO scoreInfo = this.courseTotalScoreContentSonMapper.findTotalScoreAllScoreInfo(dto.getClassId());
        if (scoreInfo == null) {
            return columnResultDTO;
        }

        scoreInfo.setIsShowStudent(resultDTO.getIsShowStudent() == null ? 1 : resultDTO.getIsShowStudent());
        scoreInfo.setIsUserLevelShow(resultDTO.getIsUserLevelShow() == null ? 1 : resultDTO.getIsUserLevelShow());
        scoreInfo.setMaxScore(MathUtils.stripTrailingZeros(scoreInfo.getMaxScore(), 1));
        scoreInfo.setMinScore(MathUtils.stripTrailingZeros(scoreInfo.getMinScore(), 1));
        scoreInfo.setAvgScore(MathUtils.stripTrailingZeros(scoreInfo.getAvgScore(), 1));

        //核实等级分制是否已设置没有初始化
        CourseTotalScoreConfigClassDTO config = new CourseTotalScoreConfigClassDTO();
        config.setClassId(dto.getClassId());
        config.setType(TotalScoreTypeEnum.ALL_SCORE.getCode());
        List<CourseTotalScoreConfigResultDTO> configList = courseTotalScoreConfigService.findCourseTotalScoreConfig(config);

        // 获取学生数量
        List<ClassStudentResultDTO> studentList = classStudentClient.studentListByClassId(dto.getClassId()).getData();
        // 获取学生数据
        studentList = studentList.stream().filter(v -> Objects.equals(ClassRoleEnum.STUDENT.getCode(), v.getClassRole())
            || Objects.equals(ClassRoleEnum.REPRESENTATIVE.getCode(), v.getClassRole())).collect(Collectors.toList());

        // 获取学生分数区段
        scoreInfo.setStudentCount(studentList.size());
        List<StudentTotalScoreBaseResultDTO> studentScoreList = this.baseMapper.studentTotalScoreColumnList(dto);
        if (configList.size() > 0) {
            boolean[] firstFlag = {true};
            List<CourseTotalScoreColumnDataResultDTO> columnList = new ArrayList<>();
            configList.forEach(item -> {
                CourseTotalScoreColumnDataResultDTO result = new CourseTotalScoreColumnDataResultDTO();
                result.setColumnTitle(item.getMin() + "-" + item.getMax());
                BigDecimal maxScore = MathUtils.stripTrailingZeros(scoreInfo.getFullScore()
                    .multiply(new BigDecimal(item.getMax())).divide(new BigDecimal(100)), 1);
                BigDecimal minScore = MathUtils.stripTrailingZeros(scoreInfo.getFullScore()
                    .multiply(new BigDecimal(item.getMin())).divide(new BigDecimal(100)), 1);
                if (firstFlag[0]) {
                    firstFlag[0] = false;
                    List<StudentTotalScoreBaseResultDTO> newList = studentScoreList.stream().filter(student ->
                        (student.getStudentScore().compareTo(minScore) >= 0 && student.getStudentScore().compareTo(maxScore) <= 0)).collect(Collectors.toList());
                    result.setColumnCount(newList.size());
                } else {
                    List<StudentTotalScoreBaseResultDTO> newList = studentScoreList.stream().filter(student ->
                        (student.getStudentScore().compareTo(minScore) >= 0 && student.getStudentScore().compareTo(maxScore) < 0)).collect(Collectors.toList());
                    result.setColumnCount(newList.size());
                }
                columnList.add(0, result);
            });
            columnResultDTO.setList(columnList);
        }

        columnResultDTO.setScoreInfo(scoreInfo);
        return columnResultDTO;
    }

}
